package com.xin.di.uav.applet.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xin.di.uav.applet.mapper.*;
import com.xin.di.uav.applet.po.*;
import com.xin.di.uav.applet.resp.*;
import com.xin.di.uav.applet.rest.BusinessRest;
import com.xin.di.uav.applet.rest.CommodityRest;
import com.xin.di.uav.applet.rest.DictionaryRest;
import com.xin.di.uav.applet.rest.OrderCommodityRest;
import com.xin.di.uav.applet.shop.service.IShoppingService;
import com.xin.di.uav.common.awt.JwtUtil;
import com.xin.di.uav.common.enums.DeliveryMethodEnum;
import com.xin.di.uav.common.enums.DictionarySubjectEnum;
import com.xin.di.uav.common.enums.ScenicSpotStatusEnum;
import com.xin.di.uav.common.utils.BeanUtil;
import com.xin.di.uav.common.utils.LocationUtils;
import com.xin.di.uav.mapper.ScenicSpotMapper;
import com.xin.di.uav.operate.mapper.PlacementPointMapper;
import com.xin.di.uav.operate.po.PlacementPoint;
import com.xin.di.uav.po.OrderCommodity;
import com.xin.di.uav.po.OrderMapper;
import com.xin.di.uav.po.ScenicSpot;
import com.xin.di.uav.user.entity.UserExtra;
import com.xin.di.uav.user.mapper.UserExtraMapper;
import com.xin.di.uav.user.order.po.OrderPO;
import com.xin.di.uav.user.order.po.Product;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @author 01430312
 */
@Service
public class ShoppingServiceImpl implements IShoppingService {

    @Autowired
    private UserExtraMapper userExtraMapper;

    @Autowired
    private PlacementPointMapper placementPointMapper;

    @Autowired
    private BusinessMapper businessMapper;

    @Autowired
    private BusinessRest businessRest;

    @Autowired
    private CommodityRest commodityRest;

    @Autowired
    private CommodityMapper commodityMapper;

    @Autowired
    private DictionaryRest dictionaryRest;


    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private OrderCommodityRest orderCommodityRest;

    @Autowired
    private ScenicSpotMapper scenicSpotMapper;


    @Autowired
    private OrderMapper orderInfoMapper;


    @Value("${delivery.overhang: 200}")
    private double deliveryOverhang;

    @Autowired
    private FileMapper fileMapper;

    @Override
    public ShoppingDataResponse getShoppingData(String placementPointId, BigDecimal longitude, BigDecimal latitude) {
        String userId = JwtUtil.getUserId();
        ShoppingDataResponse shoppingDataResponse = new ShoppingDataResponse();
        List<Dictionary> dictionaries = dictionaryRest.getListBySubject(DictionarySubjectEnum.RESCUE_SHOP_BANNER.getCode());
        if (!CollectionUtils.isEmpty(dictionaries)) {
            shoppingDataResponse.setBannerUrls(dictionaries.stream().map(Dictionary::getStrValue).collect(Collectors.toList()));
        }
        List<Business> businessList;

        QueryWrapper<UserExtra> userExtraQueryWrapper = new QueryWrapper<>();
        userExtraQueryWrapper.eq("user_id", userId);
        String scenicSpotId;
        if (ObjectUtils.isEmpty(placementPointId)) {
            shoppingDataResponse.setStatus(0);
        } else {
            PlacementPoint placementPoint = placementPointMapper.selectById(placementPointId);
            if (ObjectUtils.isEmpty(placementPoint)) {
                shoppingDataResponse.setStatus(0);
            } else {
                shoppingDataResponse.setPlacementPointName(placementPoint.getName());
                shoppingDataResponse.setExpressFee(placementPoint.getExpressFee());
                scenicSpotId = placementPoint.getScenicSpotId();
                ScenicSpot scenicSpot = scenicSpotMapper.selectById(scenicSpotId);
                if (!ObjectUtils.isEmpty(scenicSpot)) {
                    Integer status = scenicSpot.getStatus();
                    Integer placementPointStatus = placementPoint.getStatus();
                    if (status.equals(ScenicSpotStatusEnum.OFF.getValue())) {
                        //景区关闭
                        shoppingDataResponse.setStatus(2);
                    } else if (placementPointStatus.equals(ScenicSpotStatusEnum.OFF.getValue())) {
                        //投放点关闭
                        shoppingDataResponse.setStatus(3);
                    } else if (!ObjectUtils.isEmpty(longitude) && !ObjectUtils.isEmpty(latitude)) {
                        BigDecimal placementPointLatitude = placementPoint.getLatitude();
                        BigDecimal placementPointLongitude = placementPoint.getLongitude();
                        double jl = LocationUtils.getDistance(latitude.doubleValue(), longitude.doubleValue(), placementPointLatitude.doubleValue(), placementPointLongitude.doubleValue());
                        if (jl > deliveryOverhang) {
                            shoppingDataResponse.setStatus(1);
                        }
                    }
                    businessList = businessRest.getBusinessesByScenicSpotId(scenicSpotId).stream().sorted(Comparator.comparing(Business::getName, (x, y) -> {
                        Collator clt = Collator.getInstance(Locale.CHINA);
                        return clt.compare(x, y);
                    })).collect(Collectors.toList());
                    List<BusinessResponse> businessResponses = BeanUtil.copyProperties(businessList, BusinessResponse.class);
                    if (!CollectionUtils.isEmpty(businessResponses)) {
                        /**
                         * 查默认第一家商店的商品
                         */
                        String businessId = businessResponses.get(0).getId();
                        List<CommodityResponse> commodityResponses = this.getByBusinessId(businessId);
                        shoppingDataResponse.setCommodityResponses(commodityResponses);
                    }
                    shoppingDataResponse.setBusinessResponses(businessResponses);
                }

            }
            shoppingDataResponse.setPlacementPointId(placementPointId);
        }
        return shoppingDataResponse;
    }

    @Override
    public Boolean checkDistance(String placementPointId, BigDecimal longitude, BigDecimal latitude) {
        PlacementPoint placementPoint = placementPointMapper.selectById(placementPointId);
        if (ObjectUtils.isEmpty(placementPoint)) {
            throw new RuntimeException("点位不存在");
        }
        double jl = LocationUtils.getDistance(latitude.doubleValue(), longitude.doubleValue(), placementPoint.getLatitude().doubleValue(), placementPoint.getLongitude().doubleValue());
        if (jl > deliveryOverhang) {
            return true;
        }
        return false;
    }


    @Override
    public CommodityDetailResponse getCommodityDetail(String commodityId) {
        Product commodity = commodityMapper.selectById(commodityId);
        if (ObjectUtils.isEmpty(commodity)) {
            throw new RuntimeException("商品不存在");
        }
        CommodityDetailResponse commodityDetailResponse = BeanUtil.copyProperties(commodity, CommodityDetailResponse.class);
        return commodityDetailResponse;
    }


    @Override
    public List<CommodityResponse> getByBusinessId(String businessId) {
        List<CommodityResponse> commodityResponses = new ArrayList<>();
        List<Product> commodities = commodityRest.getByBusinessId(businessId);
        if (!CollectionUtils.isEmpty(commodities)) {
            commodities.forEach(commodity -> {
                CommodityResponse commodityResponse = BeanUtil.copyProperties(commodity, CommodityResponse.class);
                Integer amount = commodity.getStock();
                if (amount == 0) {
                    commodityResponse.setShowStatus(3);
                }
                commodityResponses.add(commodityResponse);
            });
        }
        return commodityResponses;
    }

    @Override
    public CommodityDetailInfoResponse getOrderDetailByOrderId(String orderId) {
        OrderPO orderInfo = orderInfoMapper.selectById(orderId);
        if (ObjectUtils.isEmpty(orderInfo)) {
            throw new RuntimeException("订单号不存在");
        }
        //1校验投放点
//        PlacementPoint placementPoint = placementPointMapper.selectById(orderInfo.getPlacementPointId());
        PlacementPoint placementPoint = null;
        if (ObjectUtils.isEmpty(placementPoint)) {
            throw new RuntimeException("投放点已关闭，请联系客服");
        }
        CommodityDetailInfoResponse commodityDetailInfoResponse = BeanUtil.copyProperties(orderInfo, CommodityDetailInfoResponse.class);
        commodityDetailInfoResponse.setPlacementPointName(placementPoint.getName());
        commodityDetailInfoResponse.setDeliveryMethod(DeliveryMethodEnum.UAV.getValue());
        Dictionary dictionary = dictionaryRest.getBySubject(DictionarySubjectEnum.DELIVERY_TIME.getCode());
        if (!ObjectUtils.isEmpty(dictionary)) {
            commodityDetailInfoResponse.setDeliveryTime(dictionary.getDecimalValue());
        }
        List<CommodityPayResponse> finalCommodityPayResponses = new ArrayList<>();
        List<OrderCommodity> orderCommodities = orderCommodityRest.getByOrderSn(orderInfo.getOrderNo());
        AtomicReference<Integer> num = new AtomicReference<>(0);
        if (!CollectionUtils.isEmpty(orderCommodities)) {
            List<String> ids = orderCommodities.stream().map(OrderCommodity::getCommodityId).collect(Collectors.toList());
            List<Product> commodities = commodityMapper.selByIds(ids);
            orderCommodities.forEach(orderCommodity -> {
                commodities.forEach(commodity -> {
                    if (orderCommodity.getCommodityId().equals(commodity.getId())) {
                        CommodityPayResponse commodityPayResponse = BeanUtil.copyProperties(commodity, CommodityPayResponse.class);
                        commodityPayResponse.setCnt(orderCommodity.getCnt());
                        commodityPayResponse.setName(orderCommodity.getName());
                        commodityPayResponse.setPrice(orderCommodity.getPrice());
                        commodityPayResponse.setIntroduction(orderCommodity.getIntroduction());
                        commodityPayResponse.setImages(orderCommodity.getImages());
                        finalCommodityPayResponses.add(commodityPayResponse);
                        num.updateAndGet(v -> v + orderCommodity.getCnt());
                    }
                });
            });
        }
        commodityDetailInfoResponse.setCommodityPayResponses(finalCommodityPayResponses);
        commodityDetailInfoResponse.setNum(num.get());
//        commodityDetailInfoResponse.setPrice(orderInfo.getPricePaid().subtract(orderInfo.getExpressFee()));
        return commodityDetailInfoResponse;
    }
}
